package main;

import java.util.List;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;

import comunicacao.GestorZooKeeper;

/**
 * Classe que fornece metodos para alterar znodes
 * especificos ao funcionamento das bases de dados
 * 
 * @author Leonardo Lino Nº45340
 * @author Diogo Pires Nº40351
 */
public class MembershipManager {

	GestorZooKeeper zKeeper;
	Watcher watcher;

	public boolean checkGlobalGroup(Watcher watcher) {
		if (zKeeper.existsZNode("/AppServersConfig", watcher) != null)
			return true;
		else
			return false;
	}

	public boolean createGlobalGroup() {
		if(zKeeper.createZNode("/AppServersConfig", CreateMode.PERSISTENT, null)){
			return true;
		}else
			return false;
	}
	
	public boolean checkGlobalConfig(Watcher watcher) {
		if (zKeeper.existsZNode("/AppServersConfig/NumTheaters", watcher) != null)
			return true;
		else
			return false;
	}

	public boolean createGlobalConfig(String numTheaters) {
		if(zKeeper.createZNode("/AppServersConfig/NumTheaters", CreateMode.PERSISTENT, numTheaters.getBytes())){
			return true;
		}else
			return false;
	}
	
	public boolean setGlobalConfigData(String numTheaters){
		if(zKeeper.setData("/AppServersConfig/NumTheaters", numTheaters, -1)){
			return true;
		}else
			return false;
	}
	
	public boolean checkDBSystemState(Watcher watcher){
		if (zKeeper.existsZNode("/AppServersConfig/State", watcher) != null)
			return true;
		else
			return false;
	}
	
	public boolean createDBSystemState() {
		if(zKeeper.createZNode("/AppServersConfig/State", CreateMode.PERSISTENT, null)){
			return true;
		}else
			return false;
	}
	
	public boolean setDBSystemState(String state){
		if(zKeeper.setData("/AppServersConfig/State", state, -1)){
			return true;
		}else
			return false;
	}
	
	public String getDBSystemState(Watcher watcher){
		String data = zKeeper.getData("/AppServersConfig/State", -1, watcher);
		return data;
	}
	
	public MembershipManager(GestorZooKeeper zKeeper, Watcher watcher) {
		this.zKeeper = zKeeper;
		this.watcher = watcher;
	}

	public boolean startGroup(String groupPath) {
		return zKeeper.createZNode(groupPath, CreateMode.PERSISTENT, null);
	}

	public boolean joinGroup(String groupPath, String memberName, String data) {
		return zKeeper.joinGroup(groupPath, memberName, data.getBytes());
	}

	public boolean electLider() {
		return true;
	}
	
	public boolean checkDBGroup(Watcher watcher) {
		if (zKeeper.existsZNode("/DBServers", watcher) != null)
			return true;
		else
			return false;
	}

	public boolean createDBGroup() {
		if(zKeeper.createZNode("/DBServers", CreateMode.PERSISTENT, null)){
			return true;
		}else
			return false;
	}
	
	public boolean checkReadyGroup(Watcher watcher) {
		if (zKeeper.existsZNode("/Ready",watcher) != null)
			return true;
		else
			return false;
	}

	public boolean createReadyGroup() {
		if(zKeeper.createZNode("/Ready", CreateMode.PERSISTENT, null))
			return true;
		else
			return false;
	}
	
	public boolean checkDBReady(Watcher watcher) {
		if (zKeeper.existsZNode("/Ready/DBready", watcher) != null)
			return true;
		else
			return false;
	}

	public boolean createDBReady(byte[] data) {
		if(zKeeper.createZNode("/Ready/DBready", CreateMode.EPHEMERAL, data)){
			return true;
		}else
			return false;
	}
	
	public boolean setDBReadyData(String Address, String port, String ServerID) {
		StringBuilder sb = new StringBuilder();
		sb.append(Address);
		sb.append(":");
		sb.append(port);
		sb.append(":");
		sb.append("dbServer" + ServerID);
		sb.append(",");
		sb.append(ServerID);
		
		if(zKeeper.setData("/Ready/DBready", sb.toString(), -1)){
			return true;
		}else
			return false;
	}
	
	public String getDBReadyData(Watcher watcher) {
		
		String data = zKeeper.getData("/Ready/DBready", -1, watcher);
		return data;
	}
	
	public boolean JoinDBGroup(String id, String address, int port) {
		StringBuilder sb = new StringBuilder();
		sb.append(address);
		sb.append(":");
		sb.append(port);
		sb.append(":");
		sb.append("dbServer" + id);
		sb.append(",");
		sb.append(id);
		
		if(zKeeper.joinGroup("/DBServers", "DB-" + id, sb.toString().getBytes())){
			return true;
		}else
			return false;
	}
	
	public boolean checkIDTracker(Watcher watcher){
		if (zKeeper.existsZNode("/DBServers/ID", watcher) != null)
			return true;
		else
			return false;
	}
	
	public boolean createIDTracker(){
		if(zKeeper.createZNode("/DBServers/ID", CreateMode.PERSISTENT, null)){
			return true;
		}else
			return false;
	}
	
	public String getCurrentID(Watcher watcher){
		String data = zKeeper.getData("/DBServers/ID", -1, watcher);
		return data;
	}
	
	public boolean setCurrentID(String ServerID) {
		if(zKeeper.setData("/DBServers/ID", ServerID, -1)){
			return true;
		}else
			return false;
	}
	
	public List<String> listDBGroup(){
		List<String> childrens = zKeeper.listGroup("/DBServers", null);
		return childrens;
	}
}
